﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TjZheng.Core.Process.Filter;
using TjZheng.Core.Process.Handle;
using TjZheng.Core.Process.Helper;
using TjZheng.Framework;
using TjZheng.Web.Helper;
using TjZheng.WeiXin.Business;
using TjZheng.WeiXin.DataEntity;
using TjZheng.Cache;
using System.Net;

namespace TjZheng.WeiXin.SDK.Pay
{
    public class ModeOneServiceProcessHandle : NativePayServiceProcessHandle
    {
        /// <summary>
        /// 订单信息
        /// </summary>
        public OrderInfo OrderInfo { get; private set; }
        public override void OnExecuting(ProcessExecutingContext filterContext)
        {
            ProcessHelper.CheckProcessFilterContext(filterContext);
            ModeOneServiceProcessContext objModeOneServiceProcessContext = filterContext.ProcessContext as ModeOneServiceProcessContext;
            if (objModeOneServiceProcessContext == null)
            {
                throw new ArgumentException("扫码支付模式一上下文ModeTwoServiceProcessContext为空");
            }
            objModeOneServiceProcessContext.CheckIntputWxPayPackage();

            WxPayPackage objIntputWxPayPackage = objModeOneServiceProcessContext.IntputWxPayPackage;
            //WxPayPackage objOutPutWxPayPackage = null;

            //检查appid和mch_id是否返回
            if (!objIntputWxPayPackage.IsValueSet("appid") || !objIntputWxPayPackage.IsValueSet("mch_id"))
            {
                throw new WxPayException("扫码支付模式一：微信系统返回的数据包缺少appid或者mch_id");
            }

            //检查openid和product_id是否返回
            if (!objIntputWxPayPackage.IsValueSet("openid") || !objIntputWxPayPackage.IsValueSet("product_id"))
            {
                throw new WxPayException("扫码支付模式一：微信系统返回的数据包缺少openid或者product_id");
            }

            string appid = Convert.ToString(objIntputWxPayPackage.GetValue("appid"));
            string mch_id = Convert.ToString(objIntputWxPayPackage.GetValue("mch_id"));

            BizMerchantInfo objBizMerchantInfo = new BizMerchantInfo();
            MerchantInfo objMerchantInfo = objBizMerchantInfo.GetRecordCache("", TimeSpan.FromSeconds(30), "AppId=@AppId AND MChId=@MChId AND IsRelease=1", new { AppId = appid, MChId = mch_id });
            objModeOneServiceProcessContext.SetMerchantInfo(objMerchantInfo);
            objModeOneServiceProcessContext.CheckMerchantInfo();

            if (objMerchantInfo.ModeOneCallBackUrl.IsNull())
            {
                throw new WxPayException("扫码支付模式一回调商户url为空");
            }
            WeiXinPackage objWeiXinPackage = this.CallBackFromMerchant(objIntputWxPayPackage, objMerchantInfo);

            InvokeResult objInvokeResult = this.CheckWeiXinPackage(objWeiXinPackage);
            if (objInvokeResult.ResultCode != "Success")
            {
                filterContext.Result = objInvokeResult;
                return;
            }

            objModeOneServiceProcessContext.SetWeiXinPackage(objWeiXinPackage);

            this.CreateOrderInfo(objWeiXinPackage);


        }

        public override InvokeResult Execute(ProcessContext objProcessContext)
        {
            ModeOneServiceProcessContext objModeOneServiceProcessContext = objProcessContext as ModeOneServiceProcessContext;

            UnifiedOrderProcessContext objUnifiedOrderProcessContext = new UnifiedOrderProcessContext();
            objUnifiedOrderProcessContext.SetMerchantInfo(objModeOneServiceProcessContext.MerchantInfo);

            //统一下单
            WxPayPackage objWxPayPackage = new WxPayPackage();
            objWxPayPackage.SetValue("body", this.OrderInfo.ProductDescription);//商品描述
            objWxPayPackage.SetValue("attach", this.OrderInfo.ProductAttach);//附加数据
            objWxPayPackage.SetValue("out_trade_no", this.OrderInfo.OutTradeNo);//随机字符串
            objWxPayPackage.SetValue("total_fee", this.OrderInfo.TotalFee);//总金额
            objWxPayPackage.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));//交易起始时间
            objWxPayPackage.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));//交易结束时间
            objWxPayPackage.SetValue("goods_tag", this.OrderInfo.ProductTag);//商品标记
            objWxPayPackage.SetValue("trade_type", "NATIVE");//交易类型

            string openId = Convert.ToString(objModeOneServiceProcessContext.IntputWxPayPackage.GetValue("openid"));
            string product_id = Convert.ToString(objModeOneServiceProcessContext.IntputWxPayPackage.GetValue("product_id"));

            objWxPayPackage.SetValue("openid", openId);
            objWxPayPackage.SetValue("product_id", product_id);

            objUnifiedOrderProcessContext.SetIntputWxPayPackage(objWxPayPackage);

            UnifiedOrderProcessHandle objUnifiedOrderProcessHandle = new UnifiedOrderProcessHandle();
            return objUnifiedOrderProcessHandle.Execute(objUnifiedOrderProcessContext);
        }



        public virtual WeiXinPackage CallBackFromMerchant(WxPayPackage objIntputWxPayPackage, MerchantInfo objMerchantInfo)
        {
            HttpWebRequest objHttpWebRequest = objMerchantInfo.ModeOneCallBackUrl.CreateHttpRequest();
            //设置POST的数据类型和长度
            objHttpWebRequest.ContentType = "text/xml";
            string xml = objIntputWxPayPackage.ConvertToXml();
            byte[] data = Encoding.UTF8.GetBytes(xml);
            objHttpWebRequest.ContentLength = data.Length;
            //往服务器写入数据
            var reqStream = objHttpWebRequest.GetRequestStream();
            reqStream.Write(data, 0, data.Length);
            reqStream.Close();

            string response = objHttpWebRequest.GetHttpResponse(Encoding.UTF8);
            return WeiXinPackage.ParseFromXml(response);
        }

        /// <summary>
        /// 执行结果若没返回Success，反馈给微信支付系统
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnResultExecute(ResultFilterContext filterContext)
        {
            if (filterContext.ExecuteResult.ResultCode != "Success")
            {
                WxPayPackage objWxPayPackage = new WxPayPackage();
                objWxPayPackage.SetValue("return_code", "FAIL");
                objWxPayPackage.SetValue("return_msg", "统一下单失败");

                SystemWebAsset.CreateContentResult(objWxPayPackage.ConvertToXml());
            }
        }

        /// <summary>
        /// 程序执行发生异常，反馈给微信支付系统
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnException(ExceptionFilterContext filterContext)
        {
            WxPayPackage objWxPayPackage = new WxPayPackage();
            objWxPayPackage.SetValue("return_code", "FAIL");
            objWxPayPackage.SetValue("return_msg", "统一下单失败");

            SystemWebAsset.CreateContentResult(objWxPayPackage.ConvertToXml());
        }
    }
}
